package de.openlaboratory.elib.dispatcher;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Properties;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;

import de.openlaboratory.elib.core.LogManager;
import de.openlaboratory.elib.utilities.ContextHelper;

public class DefaultRequestDispatcher implements RequestDispatcher
{
	private Template template;
	VelocityContext context;

	private void initVelocity()
	{
		Properties p = new Properties();

		p.setProperty("resource.loader", "class");
		p.setProperty("class.resource.loader.class",
				"org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
		p.setProperty("class.resource.loader.cache", "true");
		p.setProperty("class.resource.loader.modificationCheckInterval", "60");
		p.setProperty("parse_directive.maxdepth", "5");
		// p.setProperty("eventhandler.include.class", "org.apache.velocity.app.event.implement.IncludeRelativePath");
		
		try
		{
			Velocity.init(p);
		}
		catch (Exception e)
		{
			System.err.println("Velocity Engine Start Exception: " + e.getMessage());
		}
	}

	public DefaultRequestDispatcher(String page)
	{
		if (page.equals("VELOCITY"))
		{
			initVelocity();
			context = new VelocityContext();
			setTemplate(page);
		}
	}

	private void setTemplate(String t)
	{
		try
		{
			template = Velocity.getTemplate("de/openlaboratory/elib/templates/dashboard.vm");
		}
		catch (ResourceNotFoundException rnfe)
		{
			// couldn't find the template
			LogManager.logMessage("couldn't find the template");
		}
		catch (ParseErrorException pee)
		{
			// syntax error: problem parsing the template
			LogManager.logMessage("syntax error: problem parsing the template");
		}
		catch (MethodInvocationException mie)
		{
			// something invoked in the template
			// threw an exception
			LogManager.logMessage("something invoked in the template threw an exception");
		}
		catch (Exception e)
		{
			LogManager.logMessage("Velicity error: " + e.getLocalizedMessage());
		}
	}

	@Override
	public void forward(ServletRequest request, ServletResponse response) throws ServletException, IOException
	{
		forward((HttpServletRequest) request, (HttpServletResponse) response);
	}

	public void forward(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
	{
		PrintWriter out = response.getWriter();

		ContextHelper.buildContext(context, request);

		if (template != null)
		{
			// Velocity.mergeTemplate(template.getName(), "EN", context, out);
			template.merge(context, out);
		}
		else
		{
			out.print("Velocity error.");
		}
	}

	@Override
	public void include(ServletRequest request, ServletResponse response) throws ServletException, IOException
	{
		forward(request, response);
	}

}
